//===============================================================================
// Microsoft Architecture Strategy Team
// LitwareHR - SaaS Sample Application
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================


namespace Shp.Runtime.OfflineSitka
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    using Microsoft.Practices.EnterpriseLibrary.Data;
    using System.Xml;
    using System.Xml.Serialization;
    using System.IO;
    using System.Data.SqlClient;
    using System.Text.RegularExpressions;
    using System.Diagnostics;
    using System.ServiceModel;
    using Shp.Runtime.Sitka.ServiceGateway.SitkaClient;
    
    public class OfflineSitkaSoapService : ISitkaSoapService
    {
        /// <summary>
        /// Creates either an Entity or a Container
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Scope Create(Scope scope, Entity entity)
        {
            try
            {
                if (entity is Container)
                {
                    return OfflineSitkaSql.CreateContainer(ref scope, entity);
                }
                
                if (entity is Entity)
                {
                    Validations.IsValidContainer(scope.ContainerId);
                    Validations.IsValidEntity(entity.Id);
                    return OfflineSitkaSql.CreateEntity(ref scope, entity);
                }

                throw new ArgumentException(entity.GetType().ToString() + " is unsupported. Only Entity and Containers are valid"); 
            }
            catch (Exception ex)
            {
                throw OfflineSitkaHelper.CreateFaultException(ex);
            }
        }

        /// <summary>
        /// Gets an Entity 
        /// </summary>
        /// <param name="scope"></param>
        /// <returns></returns>
        public Entity Get(Scope scope)
        {
            try
            {
                Validations.IsValidContainer(scope.ContainerId);
                
                if (scope.EntityId != null)
                {
                    // Assume Entity
                    Validations.IsValidContainer(scope.ContainerId);
                    return OfflineSitkaSql.GetEntity(scope);
                }

                // The container exists, so return one
                Container container = new Container();
                container.Id = scope.ContainerId;
                return container;
            }
            catch (Exception ex)
            {
                throw OfflineSitkaHelper.CreateFaultException(ex);
            }
        }

        /// <summary>
        /// Updates an Entity
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Entity Update(Scope scope, Entity entity)
        {
            try
            {
                Validations.IsAnEntity(entity);
                return OfflineSitkaSql.UpdateEntity(scope, entity);
            }
            catch (Exception ex)
            {
                throw OfflineSitkaHelper.CreateFaultException(ex);
            }
        }

        /// <summary>
        /// Deletes Entities and Containers
        /// </summary>
        /// <param name="scope"></param>
        public void Delete(Scope scope)
        {
            try
            {
                Validations.IsValidContainer(scope.ContainerId);

                if (String.IsNullOrEmpty(scope.EntityId))
                {
                    OfflineSitkaSql.DeleteContainer(scope.ContainerId);
                    return;
                }

                // We assume is Delete of an Entity
                OfflineSitkaSql.DeleteEntity(scope.ContainerId, scope.EntityId);
            }
            catch (Exception ex)
            {
                throw OfflineSitkaHelper.CreateFaultException(ex);
            }
        }

        /// <summary>
        /// Query a container for entities
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        public List<Entity> Query(Scope scope, string query1)
        {
            try
            {
                // Simple checks
                Validations.IsValidateQueryStatement(query1);
                Validations.IsValidContainer(scope.ContainerId);

                return OfflineSitkaSql.QueryContainer(scope, query1);
            }
            catch (Exception ex)
            {
                throw OfflineSitkaHelper.CreateFaultException(ex);
            }
        }
    }
}
